package com.skivingcloud.admin.sys.service.impl;

import com.skivingcloud.admin.sys.entity.SysMsgDef;
import com.skivingcloud.admin.sys.entity.SysMsgStream;
import com.skivingcloud.admin.sys.entity.User;
import com.skivingcloud.admin.sys.mapper.SysMsgDefMapper;
import com.skivingcloud.admin.sys.mapper.SysMsgStreamMapper;
import com.skivingcloud.admin.sys.mapper.UserMapper;
import com.skivingcloud.admin.sys.service.ISysMsgStreamService;
import com.skivingcloud.admin.utils.JacksonJsonUtil;
import com.skivingcloud.common.exception.BusinessException;
import com.skivingcloud.common.utils.JsonUtils;
import com.skivingcloud.common.utils.PageUtils;
import com.skivingcloud.common.utils.StringUtils;
import com.skivingcloud.common.utils.UuidUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import org.apache.commons.beanutils.BeanUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import net.sf.json.JSONObject;

/**
 * <p>
 * 消息流水 服务实现类
 * </p>
 *
 * @author skivingcloud
 * @since 2022-01-29
 */
@Service
public class SysMsgStreamServiceImpl extends ServiceImpl<SysMsgStreamMapper, SysMsgStream> implements ISysMsgStreamService {

	private static Logger log = LoggerFactory.getLogger(SysMsgStreamServiceImpl.class);

	@Autowired
	private SysMsgStreamMapper msgStreamMapper;
	@Autowired
	private SysMsgDefMapper msgDefMapper;
	@Autowired
	private UserMapper userMapper;

	/**
	 * 发送消息接口
	 * 
	 * @param params {"senderId":发送用户id,"pageParam":页面参数,"msgCode":消息定义编码,"businessId":业务id,"msgContext":消息内容,"msgContextParam":消息内容参数}
	 * @return
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
    public boolean sendMsg(Map<String, Object> params) throws Exception {
		try {
			SysMsgStream msgStream = new SysMsgStream();
			msgStream.setSendTime(LocalDateTime.now());
			if (StringUtils.isNotBlank(params.get("pageParam"))) {
				msgStream.setPageParam(params.get("pageParam").toString());
			}
			msgStream.setReceiveState("1");// 未接收
			if (StringUtils.isNotBlank(params.get("msgCode"))) {
				msgStream.setMsgCode(params.get("msgCode").toString());
			}
			if (StringUtils.isNotBlank(params.get("businessId")))
				msgStream.setBusinessId(params.get("businessId").toString());
			if (StringUtils.isNotBlank(params.get("msgContext"))) {
				msgStream.setMsgContext(params.get("msgContext").toString());
			} else {
				QueryWrapper<SysMsgDef> queryWrapperStr = new QueryWrapper<SysMsgDef>();
				queryWrapperStr.eq("msg_code", params.get("msgCode").toString());
				List<SysMsgDef> def = msgDefMapper.selectList(queryWrapperStr);
				if (def.isEmpty()) {
					throw new BusinessException("没有定义编号为：" + params.get("msgCode").toString() + "的消息模板");
				}
				SysMsgDef msgDef = def.isEmpty() ? null : def.get(0);
				String msgContext = msgDef.getMsgContext();
				String msgContextParam = msgDef.getMsgContextParam();
				if (params.containsKey("msgContextParam")) {
					Map paramMap = JsonUtils.parseJSONMap(params.get("msgContextParam").toString());
					// Map paramMap =
					// JSON.parseObject(JSONObject.toJSONString(params.get("msgContextParam")).replace("\\",
					// "").replace("\"{", "{").replace("}\"", "}"), Map.class);
					String[] msgContextParams = msgContextParam.split(",");
					for (String s : msgContextParams)
						msgContext = msgContext.replaceAll(s, paramMap.get(s).toString());
				}
				msgStream.setMsgContext(msgContext);
				msgStream.setMsgContextParam(params.get("msgContextParam").toString().replace("\\", "")
						.replace("\"{", "{").replace("}\"", "}"));
			}
			if (StringUtils.isNotBlank(params.get("receiverId"))) {
				msgStream.setReceiverId(params.get("receiverId").toString());
				msgStream.setId(UuidUtil.get32UUID());
				msgStreamMapper.insert(msgStream);// 插入流水表
			}

			Map beanMap = BeanUtils.describe(msgStream);
			// 调用websocket微服务
			if (params.containsKey("msgCode")) {
				QueryWrapper<SysMsgDef> queryWrapper = new QueryWrapper<SysMsgDef>();
				queryWrapper.eq("msg_code", params.get("msgCode").toString());
				List<SysMsgDef> list = msgDefMapper.selectList(queryWrapper);
				if (list.size() != 0) {
					beanMap.put("pageUrl", list.get(0).getPageUrl());
				}
			}
			Map<String, String> map = new HashMap();
			map.put("cid", params.get("receiverId").toString());
			map.put("message", JacksonJsonUtil.objToJson(beanMap));
			try {
				WebSocketServer.sendInfo(JacksonJsonUtil.objToJson(beanMap), params.get("receiverId").toString());
			} catch (Exception e) {
				log.error("发送消息至websocket失败", e);
			}

			return true;
		} catch (Exception e) {
			throw new BusinessException("发送消息失败", e);
		}
	}

	/**
	 * 查询未读消息
	 * 
	 * @param params
	 * @return
	 */
	@Override
	public PageUtils queryUndealMsg(Map<String, Object> params, User user) {
		PageUtils pageUtils = PageUtils.getPageInfo(params);
		Page<Map<String, Object>> p = PageHelper.startPage(pageUtils.getPage(), pageUtils.getLimit());
		QueryWrapper<SysMsgStream> queryWrapperStr = new QueryWrapper<SysMsgStream>();
		JSONObject msgStream = JSONObject.fromObject(params.get("dataForm").toString());
		if (msgStream.containsKey("deal") && msgStream.get("deal").toString().equals("true")) {
			queryWrapperStr.eq("receive_state", "1");
		}
		queryWrapperStr.eq("receiver_id", user.getId());
		if (StringUtils.isNotBlank(msgStream.get("sendTime").toString())) {
			String sendTimeStr = msgStream.get("sendTime").toString();
			LocalDateTime start = LocalDateTime.parse(sendTimeStr + " 00:00:00", DateTimeFormatter.ofPattern(
					"yyyy-MM-dd HH:mm:ss"));
			LocalDateTime end = LocalDateTime.parse(sendTimeStr + " 23:59:59", DateTimeFormatter.ofPattern(
					"yyyy-MM-dd HH:mm:ss"));
			queryWrapperStr.between("send_time", start, end);
		}
		queryWrapperStr.orderByAsc("receive_state");
		queryWrapperStr.orderByDesc("send_time");
		List<SysMsgStream> list = msgStreamMapper.selectList(queryWrapperStr);
		List<Map<String, Object>> listC = new ArrayList<>();
		for (SysMsgStream ms : list) {
			Map<String, Object> map = new HashMap<>();
			map.put("id", ms.getId());
			map.put("msg_code", ms.getMsgCode());
			map.put("msg_context", ms.getMsgContext());
			map.put("sender_id", ms.getSenderId());
			map.put("receiver_id", ms.getReceiverId());
			map.put("business_id", ms.getBusinessId());
			map.put("send_time", ms.getSendTime());
			map.put("receive_state", ms.getReceiveState());
			map.put("receive_time", ms.getReceiveTime());
			map.put("page_param", ms.getPageParam());
			map.put("msg_context_param", ms.getMsgContextParam());
			QueryWrapper<SysMsgDef> queryWrapper = new QueryWrapper<SysMsgDef>();
			queryWrapper.eq("msg_code", ms.getMsgCode());
			List<SysMsgDef> msDef = msgDefMapper.selectList(queryWrapper);
			if (!msDef.isEmpty()) {
				map.put("page_type", msDef.get(0).getPageType());
				map.put("page_url", msDef.get(0).getPageUrl());
			}
			User userS = userMapper.selectById(ms.getSenderId());
			if (userS != null) {
				map.put("sender_name", userS.getStaffName());
			} else {
				map.put("sender_name", ms.getSenderId());
			}
			map.put("receiver_name", user.getStaffName());
			map.put("id", ms.getId());
			listC.add(map);
		}
		pageUtils = new PageUtils(p);
		pageUtils.setList(listC);
		return pageUtils;
	}

	/**
	 * 查询消息
	 * 
	 * @param params
	 * @return
	 */
	@Override
	public PageUtils queryPage(Map<String, Object> params) {
		PageUtils pageUtils = PageUtils.getPageInfo(params);
		Page<Map<String, Object>> p = PageHelper.startPage(pageUtils.getPage(), pageUtils.getLimit());
		JSONObject msgStream = JSONObject.fromObject(params.get("dataForm"));
		QueryWrapper<SysMsgStream> queryWrapperStr = new QueryWrapper<SysMsgStream>();
		
		if (StringUtils.isNotBlank(msgStream.get("receiveState"))) {
			queryWrapperStr.eq("receive_state", msgStream.get("receiveState").toString());
		}

		if (StringUtils.isNotBlank(msgStream.get("sendTime"))) {
			String sendTimeStr = msgStream.get("sendTime").toString();
			LocalDateTime start = LocalDateTime.parse(sendTimeStr + " 00:00:00", DateTimeFormatter.ofPattern(
					"yyyy-MM-dd HH:mm:ss"));
			LocalDateTime end = LocalDateTime.parse(sendTimeStr + " 23:59:59", DateTimeFormatter.ofPattern(
					"yyyy-MM-dd HH:mm:ss"));
			queryWrapperStr.between("send_time", start, end);
		}
		queryWrapperStr.orderByDesc("send_time");
		List<SysMsgStream> list = msgStreamMapper.selectList(queryWrapperStr);
		List<Map<String, Object>> listC = new ArrayList<>();
		for (SysMsgStream ms : list) {
			Map<String, Object> map = new HashMap<>();
			map.put("id", ms.getId());
			map.put("msg_code", ms.getMsgCode());
			map.put("msg_context", ms.getMsgContext());
			map.put("sender_id", ms.getSenderId());
			map.put("receiver_id", ms.getReceiverId());
			map.put("business_id", ms.getBusinessId());
			map.put("send_time", ms.getSendTime());
			map.put("receive_state", ms.getReceiveState());
			map.put("receive_time", ms.getReceiveTime());
			map.put("page_param", ms.getPageParam());
			map.put("msg_context_param", ms.getMsgContextParam());
			QueryWrapper<SysMsgDef> queryWrapper = new QueryWrapper<SysMsgDef>();
			queryWrapper.eq("msg_code", ms.getMsgCode());
			List<SysMsgDef> msDef = msgDefMapper.selectList(queryWrapper);
			if (!msDef.isEmpty()) {
				map.put("page_type", msDef.get(0).getPageType());
				map.put("page_url", msDef.get(0).getPageUrl());
			}
			User userS = userMapper.selectById(ms.getSenderId());
			if (userS != null) {
				map.put("sender_name", userS.getStaffName());
			} else {
				map.put("sender_name", ms.getSenderId());
			}
			User user = userMapper.selectById(ms.getReceiverId());
			if (user != null) {
				map.put("receiver_name", user.getStaffName());
			} else {
				map.put("receiver_name", ms.getReceiverId());
			}
			map.put("id", ms.getId());
			listC.add(map);
		}
		pageUtils = new PageUtils(p);
		pageUtils.setList(listC);
		return pageUtils;
	}

	/**
	 * 主键获取
	 * 
	 * @param id
	 * @return
	 * @throws Exception
	 */
	@Override
	public SysMsgStream selectById(String id) throws Exception {
		SysMsgStream sysMsgStream = msgStreamMapper.selectById(id);
		QueryWrapper<SysMsgDef> queryWrapper = new QueryWrapper<SysMsgDef>();
		queryWrapper.eq("msg_code", sysMsgStream.getMsgCode());
		List<SysMsgDef> msDef = msgDefMapper.selectList(queryWrapper);
		if (!msDef.isEmpty()) {
			sysMsgStream.setPageType(msDef.get(0).getPageType());
			sysMsgStream.setPageUrl(msDef.get(0).getPageUrl());
		}
		User user = userMapper.selectById(sysMsgStream.getSenderId());
		if (user != null) {
			sysMsgStream.setSenderName(user.getStaffName());
		} else {
			sysMsgStream.setSenderName(sysMsgStream.getSenderId());
		}
		return sysMsgStream;
	}

	/**
	 * 主键获取
	 * 
	 * @param id
	 * @return
	 * @throws Exception
	 */
	@Override
	public SysMsgStream selectMapById(String id) throws Exception {
		SysMsgStream sysMsgStream = msgStreamMapper.selectById(id);
		QueryWrapper<SysMsgDef> queryWrapper = new QueryWrapper<SysMsgDef>();
		queryWrapper.eq("msg_code", sysMsgStream.getMsgCode());
		List<SysMsgDef> msDef = msgDefMapper.selectList(queryWrapper);
		if (!msDef.isEmpty()) {
			sysMsgStream.setPageType(msDef.get(0).getPageType());
			sysMsgStream.setPageUrl(msDef.get(0).getPageUrl());
		}
		User user = userMapper.selectById(sysMsgStream.getSenderId());
		if (user != null) {
			sysMsgStream.setSenderName(user.getStaffName());
		} else {
			sysMsgStream.setSenderName(sysMsgStream.getSenderId());
		}
		return sysMsgStream;
	}

	/**
	 * 新增消息
	 * 
	 * @param sysMsgStream
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
    public void saveMe(SysMsgStream sysMsgStream) {
		if (StringUtils.isBlank(sysMsgStream.getId()))
			sysMsgStream.setId(UuidUtil.get32UUID());
		msgStreamMapper.insert(sysMsgStream);

	}

	/**
	 * 更新信息
	 * 
	 * @param sysMsgStream
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
    public void update(SysMsgStream sysMsgStream) {
		msgStreamMapper.updateById(sysMsgStream);

	}

	/**
	 * 删除信息
	 * 
	 * @param ids
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
    public void deleteBatch(String[] ids) {
		msgStreamMapper.deleteBatchIds(Arrays.asList(ids));
	}

	/**
	 * 获取接收人未读的消息数
	 * 
	 * @param receiverId
	 * @return
	 */
	@Override
	public int getUndealMsgNum(String receiverId) {
		return msgStreamMapper.getUndealMsgNum(receiverId);
	}

	/**
	 * 标记为已读
	 * 
	 * @param ids
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
    public void deal(String[] ids) {
		for (String id : ids)
			msgStreamMapper.deal(id);

	}
	
}
